﻿using System;
using System.Collections.Generic;
using System.Text;
using AMS.DataAccess.Properties;

namespace AMS.DataAccess
{
    /// <summary>
    /// 一个辅助构造SQL语句时字符串操作的类
    /// </summary>
    public static class SqlStringUtils
    {
        /// <summary>
        /// 将value 用单引号'引起来，如果是空字符则不处理，直接返回原内容
        /// </summary>
        /// <param name="value">要操作的字符串</param>
        /// <returns>处理后的结果</returns>
        public static string QuotedString(string value)
        {
            return QuotedString(value, false);
        }

        /// <summary>
        /// 将value 用单引号'引起来。如果是空字符，依据processNullValue来判断：
        /// processNullValue 为 true时,
        ///     1. 如果是null, 则返回字符串 NULL;
        ///     2. 如果是string.Empty，则返回''.
        /// processNullValue 为 false 时, 返回字符串 NULL.
        /// </summary>
        /// <param name="value">要操作的字符串</param>
        /// <param name="processNullValue">一个标识，表明当 value 是空的时候，是否处理它</param>
        /// <returns>转换后的内容</returns>
        public static string QuotedString(string value, bool processNullValue)
        {
            if (string.IsNullOrEmpty(value))
            {
                if (!processNullValue)
                {
                    return value;
                }
                else if (value == null)
                {
                    return "NULL";
                }
                else
                {
                    return "''";
                }
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("'");
                sb.Append(value.Replace("'", "''"));
                sb.Append("'");

                return sb.ToString();
            }
        }

        /// <summary>
        /// 将数据转换成string, 对于不同的类型有不同的处理。
        /// 1. string类型，将得到：'value';
        /// 2. 数值类型、枚举、char，将得到：value;
        /// 3. 日期类型，将得到：'yyyy-MM-dd HH:mm:ss';
        /// 4. null或DBNull将得到 NULL;
        /// 5. 其它类型的 object 将得到 'value.ToString()';
        /// </summary>
        /// <param name="value">要转换的内容</param>
        /// <returns>转换后的字符串</returns>
        public static string ObjectToSqlString(object value)
        {
            if (value == null || value == DBNull.Value)
            {
                return "NULL";
            }

            IConvertible convertible = value.GetType().GetInterface("IConvertible") as IConvertible;
            if (convertible != null)
            {
                switch (convertible.GetTypeCode())
                {
                    case TypeCode.String:
                        return QuotedString(value as string, true);

                    case TypeCode.DateTime:
                        return string.Format("'{0}'", DateTimeToString((DateTime)value, DateTimeType.DateTime));

                    case TypeCode.Char:
                        return ((int)value).ToString();

                    case TypeCode.DBNull:
                        return "NULL";

                    case TypeCode.Empty:
                        // 不会出现
                        throw new NotImplementedException();

                    case TypeCode.Object:
                        if (value is Guid)
                        {
                            return string.Format("'{0}'", value.ToString());
                        }
                        else
                        {
                            return string.Format("'{0}'", value);
                        }

                    default:
                        // 数值类型
                        return value.ToString();
                }
            }
            else
            {
                return string.Format("'{0}'", value);
            }
        }

        /// <summary>
        /// 将日期根据需要的类型转换成字符串表示
        /// </summary>
        /// <param name="value">日期值</param>
        /// <param name="type">要转换的类型</param>
        /// <returns>日期的字符串表示</returns>
        public static string DateTimeToString(DateTime value, DateTimeType type)
        {
            string strValue = string.Empty;
            switch (type)
            {
                case DateTimeType.DateTime:
                    strValue = value.ToString("yyyy-MM-dd HH:mm:ss");
                    break;

                case DateTimeType.Date:
                    strValue = value.ToString("yyyy-MM-dd");
                    break;

                default:
                    throw new NotImplementedException(Resources.DateTimeTypeNotImplemented);
            }

            return strValue;
        }

        #region List to String
        /// <summary>
        /// 将 int 类型的集合转换成字符串，并用半角的逗号和一个空格(, )作为分隔符
        /// </summary>
        /// <param name="intList">要转换的集合</param>
        /// <returns>转换后字符串</returns>
        public static string IntListToString(ICollection<int> intList)
        {
            return IntListToString(intList, ", ");
        }

        /// <summary>
        /// 将 int 类型的集合转换成字符串，并用指定的分隔符
        /// </summary>
        /// <param name="intList">要转换的集合</param>
        /// <param name="seperator">指定的分隔符</param>
        /// <returns>转换后字符串</returns>
        public static string IntListToString(ICollection<int> intList, string seperator)
        {
            if (intList.Count == 0)
            {
                return string.Empty;
            }

            List<string> slist = new List<string>();
            foreach (int item in intList)
            {
                slist.Add(item.ToString());
            }

            return string.Join(seperator, slist.ToArray());
        }

        /// <summary>
        /// 将字符串集合转换成字符串，并用半角的逗号和一个空格(, )作为分隔符
        /// </summary>
        /// <param name="stringList">要转换的集合</param>
        /// <returns>转换后字符串</returns>
        public static string StringListToString(ICollection<string> stringList)
        {
            return StringListToString(stringList, ", ");
        }

        /// <summary>
        /// 将字符串集合转换成字符串，并用指定的分隔符
        /// </summary>
        /// <param name="stringList">要转换的集合</param>
        /// <param name="seperator">指定的分隔符</param>
        /// <returns>转换后字符串</returns>
        public static string StringListToString(ICollection<string> stringList, string seperator)
        {
            if (stringList.Count == 0)
            {
                return string.Empty;
            }

            List<string> slist = new List<string>();
            foreach (string s in stringList)
            {
                slist.Add(QuotedString(s));
            }

            return string.Join(seperator, slist.ToArray());
        }

        /// <summary>
        /// 将时间的集合转换成字符串，并用半角的逗号和一个空格(, )作为分隔符
        /// </summary>
        /// <param name="dtList">要转换的集合</param>
        /// <param name="type">时间类型</param>
        /// <returns>转换后字符串</returns>
        public static string DateTomeListToString(ICollection<DateTime> dtList, DateTimeType type)
        {
            return DateTomeListToString(dtList, type, ", ");
        }

        /// <summary>
        /// 将时间的集合转换成字符串，并用指定的分隔符
        /// </summary>
        /// <param name="dateTimeList">要转换的集合</param>
        /// <param name="type">时间类型</param>
        /// <param name="seperator">指定的分隔符</param>
        /// <returns>转换后字符串</returns>
        public static string DateTomeListToString(ICollection<DateTime> dateTimeList, DateTimeType type, string seperator)
        {
            if (dateTimeList.Count == 0)
            {
                return string.Empty;
            }

            string format = type == DateTimeType.Date ? "yyyy-MM-dd" : "yyyy-MM-dd HH:mm:ss:fff";
            List<string> slist = new List<string>();
            foreach (DateTime dt in dateTimeList)
            {
                slist.Add(QuotedString(dt.ToString(format)));
            }

            return string.Join(seperator, slist.ToArray());
        }

        /// <summary>
        /// 将枚举的集合转换成字符串，并用半角的逗号和一个空格(, )作为分隔符
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="values">要转换的集合</param>
        /// <returns>转换后字符串</returns>
        public static string EnumListToString<T>(ICollection<T> values)
        {
            return EnumListToString<T>(values, ", ");
        }

        /// <summary>
        /// 将字符串集合转换成字符串，并用指定的分隔符
        /// </summary>
        /// <typeparam name="T">枚举类型</typeparam>
        /// <param name="values">要转换的集合</param>
        /// <param name="seperator">指定的分隔符</param>
        /// <returns>转换后字符串</returns>
        public static string EnumListToString<T>(ICollection<T> values, string seperator)
        {
            if (!typeof(T).IsSubclassOf(typeof(Enum)))
            {
                throw new ArgumentException(Resources.EnumTypeRequired);
            }

            List<string> list = new List<string>();
            foreach (T item in values)
            {
                list.Add(Convert.ToInt32(item).ToString());
            }

            return string.Join(seperator, list.ToArray());
        }
        #endregion
    }
}
